#include <sys/types.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <getopt.h>
#include <string.h>

#include "common.h"

#define CHUNKER_PATH "/tmp/dboy"
#define CHUNKER_CURRENT CHUNKER_PATH"/current"
#define CHUNKER_GOING   CHUNKER_PATH"/going"
#define CHUNKER_DETACH  CHUNKER_PATH"/detach"
#define CHUNKER_PREVIOUS CHUNKER_PATH"/previous"
#define CHUNKER_PREVIOUS_TMP CHUNKER_PATH"/previous.tmp"
#define CHUNKER_REMOVED_TMP CHUNKER_PATH"/removed.tmp"
#define CHUNKER_FINALIZED_TMP CHUNKER_PATH"/finalized.tmp"
#define CHUNKER_CURRENT_VERSION"/version"

#define CHUNKER_MODE S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IROTH



struct chunker_info
{
    unsigned int storageid;
    char ip[16];
    unsigned int port;
    unsigned long total;
    unsigned long avail;
    unsigned long used;
    int trackerfd;
    
};

int chunker_get_connected_socket(const char *dstip)
{
    struct sockaddr_in server = {0};
    int sockfd;

    server.sin_family = AF_INET;
    server.sin_port = htons(CHKPORT);
    inet_pton(AF_INET,dstip,&server.sin_addr);
    if ((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0) {
        printf("%s:create socket failed\n",__FUNCTION__);
        return -1;
    }    

    if (connect(sockfd,(struct sockaddr*)&server,sizeof(server)) < 0) {
        printf("%s:connect failed\n",__FUNCTION__);
        return -1;
    }

    return sockfd; 
}

int chunker_init()
{
    if (access(CHUNKER_PATH,F_OK) < 0) {
        if (mkdir(CHUNKER_PATH,CHUNKER_MODE) < 0) {
            printf("%s:mkdir %s failed\n",__FUNCTION__,CHUNKER_PATH);
            return -1;
        }
    }
    if (access(CHUNKER_CURRENT,F_OK) < 0) {
        if (mkdir(CHUNKER_CURRENT,CHUNKER_MODE) < 0) {
            printf("%s:mkdir %s failed\n",__FUNCTION__,CHUNKER_CURRENT);
            return -1;
        }
    }
    if (access(CHUNKER_GOING,F_OK) < 0) {
        if (mkdir(CHUNKER_GOING,CHUNKER_MODE) < 0) {
            printf("%s:mkdir %s failed\n",__FUNCTION__,CHUNKER_GOING);
            return -1;
        }
    }
    if (access(CHUNKER_DETACH,F_OK) < 0) {
        if (mkdir(CHUNKER_DETACH,CHUNKER_MODE) < 0) {
            printf("%s:mkdir %s failed\n",__FUNCTION__,CHUNKER_DETACH);
            return -1;
        }
    }
}

int chunker_register_tracker(struct chunker_info *info)
{
    char buf[64] = {0};
    struct cadoop_header *head = NULL;
    struct chunker_register_cmd *cmd= NULL;

    head = (struct cadoop_header *)buf;
    cmd = (struct chunk_register_cmd*)(buf+sizeof(struct cadoop_header));
    

    head->magic = htonl(MAGIC_NUMBER);
    head->cmd = CH_CHUNKER_REGISTER;
    head->type = 0;
    head->checksum = htons(0);
    head->payload = htonl(sizeof(struct chunker_register_cmd));

    cmd->storageid = htonl(info->storageid);
    strncpy(cmd->ip,info->ip,16);
    cmd->port = htons(info->port);
    cmd->total = htonl(info->total);
    cmd->avail = htonl(info->avail);
    cmd->used = htonl(info->used);

    if (write(info->trackerfd,buf,sizeof(struct cadoop_header) + sizeof(struct chunker_register_cmd)) < 0) {
        perror("chunker_register_tracker:");
        return -1;
    }
    return 0;
}

int main(int argc,char **argv)
{

    int sockfd;
    const char *serverip = NULL;
    struct sockaddr_in local = {0};
    socklen_t sklen = 0;
    struct chunker_info info = {0};
    int storageid = 0;
    int opt;
    
    while((opt = getopt(argc,argv,"i:s:")) != -1) {
        switch(opt) {
            case 'i':
                storageid = atoi(optarg);
                break;
            case 's':
                strncpy(info.ip,optarg,16);
                break;
            default:
                printf("no\n");
                
        }
    } 

    if ((sockfd = chunker_get_connected_socket(info.ip)) < 0) {
        return -1;
    }

    if (getsockname(AF_INET,(struct sockaddr*)&local,&sklen) < 0) {
    }

    info.storageid=storageid;
    info.port = local.sin_port;
    info.total = 0xFF;
    info.avail = 0xF0;
    info.used = 0x0F;
    info.trackerfd = sockfd;
    

    chunker_init();
    chunker_register_tracker(&info);
    getchar();
    printf("chunker\n");
    return 0;
}

